#define CV_NO_BACKWARD_COMPATIBILITY

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

//Desenha kernel no formato diamante
cv::Mat DrawDiamondKernel (int size)
{
	if(size % 2 == 0)
		size++;

	cv::Mat diamond(size, size, CV_8U, cv::Scalar(1));

	int numZeros = size/2;
	for (int i = 0; i < size/2; ++i)
	{
		for (int j = 0; j < numZeros; ++j)
			diamond.at<uchar>(i, j) = 0;
		
		numZeros--;
	}

	numZeros = size/2;
	for (int i = size-1; i > size/2; --i)
	{
		for (int j = 0; j < numZeros; ++j)
			diamond.at<uchar>(i, j) = 0;
		
		numZeros--;
	}

	numZeros = size/2;
	for (int i = size-1; i > size/2; --i)
	{
		for (int j = size-1; j > numZeros; --j)
			diamond.at<uchar>(i, j) = 0;
		
		numZeros++;
	}

	numZeros = size/2;
	for (int i = 0; i < size/2; ++i)
	{
		for (int j = size-1; j > numZeros; --j)
			diamond.at<uchar>(i, j) = 0;
		
		numZeros++;
	}

	return diamond;
}

int main( int argc, char** argv )
{
	cv::Mat grayImg, openImg, subImg, thrImg, closeImg;

    char* filename = argc == 2 ? argv[1] : (char*)"../imgs/14.jpg";
    if( (grayImg = cv::imread(filename,0)).data == 0 )
        return -1;

	cv::medianBlur(grayImg,grayImg,5);

    //imagem escala de cinza
    cv::namedWindow("Gray Image",0);
	cv::imshow("Gray Image",grayImg);	

	//Open
	int width = 91, height = width/3;
	cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(width,height), cv::Point(width/2,height/2));
	cv::morphologyEx(grayImg, openImg, CV_MOP_OPEN, kernel);	
	cv::namedWindow("Open Image",0);
	cv::imshow("Open Image",openImg);

	//subtraindo imagem
	subImg = grayImg - openImg;
	cv::namedWindow("Sub Image",0);
	cv::imshow("Sub Image",subImg);

	//Threshold
	cv::Scalar threshVal = cv::mean(subImg);
	//cv::threshold(subImg,thrImg, threshVal[0], 255.0, cv::THRESH_BINARY);
	cv::adaptiveThreshold(grayImg,thrImg,255.0,CV_ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY,31,10.0);

	cv::namedWindow("Threshold Image",0);
	cv::imshow("Threshold Image",thrImg);
	
	//Open Diamond
	int diamondSize = 9;
	cv::Mat diamond = DrawDiamondKernel(diamondSize);
	std::cout << diamond << std::endl;

	cv::morphologyEx(thrImg, openImg, CV_MOP_OPEN, diamond, cv::Point(diamondSize/2,diamondSize/2));
	cv::namedWindow("Open Image 2",0);
	cv::imshow("Open Image 2",openImg);

	//Close
	width = 51;
	height = width/3;
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(width,height), cv::Point(width/2,height/2));
	cv::morphologyEx(openImg, closeImg, CV_MOP_CLOSE, element);
	cv::namedWindow("Close Image",0);
	cv::imshow("Close Image",closeImg);

	cv::morphologyEx(closeImg, openImg, CV_MOP_OPEN, element);
	cv::namedWindow("Open Image 3",0);
	cv::imshow("Open Image 3",openImg);

	cv::waitKey();
    return 0;
}
